home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-10-28 | 74.4 KB | 1,981 lines |
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- NNNNAAAAMMMMEEEE
- perlfaq4 - Data Manipulation ($Revision: 1.26 $, $Date:
- 1998/08/05 12:04:00 $)
-
- DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
- The section of the FAQ answers question related to the
- manipulation of data as numbers, dates, strings, arrays,
- hashes, and miscellaneous data issues.
-
- DDDDaaaattttaaaa:::: NNNNuuuummmmbbbbeeeerrrrssss
- WWWWhhhhyyyy aaaammmm IIII ggggeeeettttttttiiiinnnngggg lllloooonnnngggg ddddeeeecccciiiimmmmaaaallllssss ((((eeeegggg,,,, 11119999....9999444499999999999999999999999999999999999999999999))))
- iiiinnnnsssstttteeeeaaaadddd ooooffff tttthhhheeee nnnnuuuummmmbbbbeeeerrrrssss IIII sssshhhhoooouuuulllldddd bbbbeeee ggggeeeettttttttiiiinnnngggg ((((eeeegggg,,,, 11119999....99995555))))????
-
- The infinite set that a mathematician thinks of as the real
- numbers can only be approximate on a computer, since the
- computer only has a finite number of bits to store an
- infinite number of, um, numbers.
-
- Internally, your computer represents floating-point numbers
- in binary. Floating-point numbers read in from a file or
- appearing as literals in your program are converted from
- their decimal floating-point representation (eg, 19.95) to
- the internal binary representation.
-
- However, 19.95 can't be precisely represented as a binary
- floating-point number, just like 1/3 can't be exactly
- represented as a decimal floating-point number. The
- computer's binary representation of 19.95, therefore, isn't
- exactly 19.95.
-
- When a floating-point number gets printed, the binary
- floating-point representation is converted back to decimal.
- These decimal numbers are displayed in either the format you
- specify with _p_r_i_n_t_f(), or the current output format for
- numbers (see the section on $# in the _p_e_r_l_v_a_r manpage if you
- use print. $# has a different default value in Perl5 than
- it did in Perl4. Changing $# yourself is deprecated.
-
- This affects aaaallllllll computer languages that represent decimal
- floating-point numbers in binary, not just Perl. Perl
- provides arbitrary-precision decimal numbers with the
- Math::BigFloat module (part of the standard Perl
- distribution), but mathematical operations are consequently
- slower.
-
- To get rid of the superfluous digits, just use a format (eg,
- printf("%.2f", 19.95)) to get the required precision. See
- the section on _F_l_o_a_t_i_n_g-_p_o_i_n_t _A_r_i_t_h_m_e_t_i_c in the _p_e_r_l_o_p
- manpage.
-
-
-
-
-
-
- Page 1 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- WWWWhhhhyyyy iiiissssnnnn''''tttt mmmmyyyy ooooccccttttaaaallll ddddaaaattttaaaa iiiinnnntttteeeerrrrpppprrrreeeetttteeeedddd ccccoooorrrrrrrreeeeccccttttllllyyyy????
-
- Perl only understands octal and hex numbers as such when
- they occur as literals in your program. If they are read in
- from somewhere and assigned, no automatic conversion takes
- place. You must explicitly use _o_c_t() or _h_e_x() if you want
- the values converted. _o_c_t() interprets both hex ("0x350")
- numbers and octal ones ("0350" or even without the leading
- "0", like "377"), while _h_e_x() only converts hexadecimal
- ones, with or without a leading "0x", like "0x255", "3A",
- "ff", or "deadbeef".
-
- This problem shows up most often when people try using
- _c_h_m_o_d(), _m_k_d_i_r(), _u_m_a_s_k(), or _s_y_s_o_p_e_n(), which all want
- permissions in octal.
-
- chmod(644, $file); # WRONG -- perl -w catches this
- chmod(0644, $file); # right
-
-
- DDDDooooeeeessss ppppeeeerrrrllll hhhhaaaavvvveeee aaaa rrrroooouuuunnnndddd ffffuuuunnnnccccttttiiiioooonnnn???? WWWWhhhhaaaatttt aaaabbbboooouuuutttt _c_e_i_l() and
- _f_l_o_o_r()? Trig functions?
-
- Remember that _i_n_t() merely truncates toward 0. For rounding
- to a certain number of digits, _s_p_r_i_n_t_f() or _p_r_i_n_t_f() is
- usually the easiest route.
-
- printf("%.3f", 3.1415926535); # prints 3.142
-
- The POSIX module (part of the standard perl distribution)
- implements _c_e_i_l(), _f_l_o_o_r(), and a number of other
- mathematical and trigonometric functions.
-
- use POSIX;
- $ceil = ceil(3.5); # 4
- $floor = floor(3.5); # 3
-
- In 5.000 to 5.003 Perls, trigonometry was done in the
- Math::Complex module. With 5.004, the Math::Trig module
- (part of the standard perl distribution) implements the
- trigonometric functions. Internally it uses the
- Math::Complex module and some functions can break out from
- the real axis into the complex plane, for example the
- inverse sine of 2.
-
- Rounding in financial applications can have serious
- implications, and the rounding method used should be
- specified precisely. In these cases, it probably pays not
- to trust whichever system rounding is being used by Perl,
- but to instead implement the rounding function you need
- yourself.
-
-
-
-
- Page 2 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- HHHHoooowwww ddddoooo IIII ccccoooonnnnvvvveeeerrrrtttt bbbbiiiittttssss iiiinnnnttttoooo iiiinnnnttttssss????
-
- To turn a string of 1s and 0s like 10110110 into a scalar
- containing its binary value, use the _p_a_c_k() function
- (documented in the section on _p_a_c_k in the _p_e_r_l_f_u_n_c manpage):
-
- $decimal = pack('B8', '10110110');
-
- Here's an example of going the other way:
-
- $binary_string = join('', unpack('B*', "\x29"));
-
-
- HHHHoooowwww ddddoooo IIII mmmmuuuullllttttiiiippppllllyyyy mmmmaaaattttrrrriiiicccceeeessss????
-
- Use the Math::Matrix or Math::MatrixReal modules (available
- from CPAN) or the PDL extension (also available from CPAN).
-
- HHHHoooowwww ddddoooo IIII ppppeeeerrrrffffoooorrrrmmmm aaaannnn ooooppppeeeerrrraaaattttiiiioooonnnn oooonnnn aaaa sssseeeerrrriiiieeeessss ooooffff iiiinnnntttteeeeggggeeeerrrrssss????
-
- To call a function on each element in an array, and collect
- the results, use:
-
- @results = map { my_func($_) } @array;
-
- For example:
-
- @triple = map { 3 * $_ } @single;
-
- To call a function on each element of an array, but ignore
- the results:
-
- foreach $iterator (@array) {
- &my_func($iterator);
- }
-
- To call a function on each integer in a (small) range, you
- ccccaaaannnn use:
-
- @results = map { &my_func($_) } (5 .. 25);
-
- but you should be aware that the .. operator creates an
- array of all integers in the range. This can take a lot of
- memory for large ranges. Instead use:
-
- @results = ();
- for ($i=5; $i < 500_005; $i++) {
- push(@results, &my_func($i));
- }
-
-
-
-
-
-
- Page 3 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- HHHHoooowwww ccccaaaannnn IIII oooouuuuttttppppuuuutttt RRRRoooommmmaaaannnn nnnnuuuummmmeeeerrrraaaallllssss????
-
- Get the http://www.perl.com/CPAN/modules/by-module/Roman
- module.
-
- WWWWhhhhyyyy aaaarrrreeeennnn''''tttt mmmmyyyy rrrraaaannnnddddoooommmm nnnnuuuummmmbbbbeeeerrrrssss rrrraaaannnnddddoooommmm????
-
- The short explanation is that you're getting pseudorandom
- numbers, not random ones, because computers are good at
- being predictable and bad at being random (despite
- appearances caused by bugs in your programs :-). A longer
- explanation is available on
- http://www.perl.com/CPAN/doc/FMTEYEWTK/random, courtesy of
- Tom Phoenix. John von Neumann said, ``Anyone who attempts
- to generate random numbers by deterministic means is, of
- course, living in a state of sin.''
-
- You should also check out the Math::TrulyRandom module from
- CPAN. It uses the imperfections in your system's timer to
- generate random numbers, but this takes quite a while. If
- you want a better pseudorandom generator than comes with
- your operating system, look at ``Numerical Recipes in C'' at
- http://nr.harvard.edu/nr/bookc.html .
-
- DDDDaaaattttaaaa:::: DDDDaaaatttteeeessss
- HHHHoooowwww ddddoooo IIII ffffiiiinnnndddd tttthhhheeee wwwweeeeeeeekkkk----ooooffff----tttthhhheeee----yyyyeeeeaaaarrrr////ddddaaaayyyy----ooooffff----tttthhhheeee----yyyyeeeeaaaarrrr????
-
- The day of the year is in the array returned by _l_o_c_a_l_t_i_m_e()
- (see the section on _l_o_c_a_l_t_i_m_e in the _p_e_r_l_f_u_n_c manpage):
-
- $day_of_year = (localtime(time()))[7];
-
- or more legibly (in 5.004 or higher):
-
- use Time::localtime;
- $day_of_year = localtime(time())->yday;
-
- You can find the week of the year by dividing this by 7:
-
- $week_of_year = int($day_of_year / 7);
-
- Of course, this believes that weeks start at zero. The
- Date::Calc module from CPAN has a lot of date calculation
- functions, including day of the year, week of the year, and
- so on. Note that not all business consider ``week 1'' to
- be the same; for example, American business often consider
- the first week with a Monday in it to be Work Week #1,
- despite ISO 8601, which consider WW1 to be the frist week
- with a Thursday in it.
-
-
-
-
-
-
- Page 4 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- HHHHoooowwww ccccaaaannnn IIII ccccoooommmmppppaaaarrrreeee ttttwwwwoooo ddddaaaatttteeeessss aaaannnndddd ffffiiiinnnndddd tttthhhheeee ddddiiiiffffffffeeeerrrreeeennnncccceeee????
-
- If you're storing your dates as epoch seconds then simply
- subtract one from the other. If you've got a structured
- date (distinct year, day, month, hour, minute, seconds
- values) then use one of the Date::Manip and Date::Calc
- modules from CPAN.
-
- HHHHoooowwww ccccaaaannnn IIII ttttaaaakkkkeeee aaaa ssssttttrrrriiiinnnngggg aaaannnndddd ttttuuuurrrrnnnn iiiitttt iiiinnnnttttoooo eeeeppppoooocccchhhh sssseeeeccccoooonnnnddddssss????
-
- If it's a regular enough string that it always has the same
- format, you can split it up and pass the parts to timelocal
- in the standard Time::Local module. Otherwise, you should
- look into the Date::Calc and Date::Manip modules from CPAN.
-
- HHHHoooowwww ccccaaaannnn IIII ffffiiiinnnndddd tttthhhheeee JJJJuuuulllliiiiaaaannnn DDDDaaaayyyy????
-
- Neither Date::Manip nor Date::Calc deal with Julian days.
- Instead, there is an example of Julian date calculation that
- should help you in
- http://www.perl.com/CPAN/authors/David_Muir_Sharnoff/modules/Time/JulianDay.pm.gz
- .
-
- DDDDooooeeeessss PPPPeeeerrrrllll hhhhaaaavvvveeee aaaa yyyyeeeeaaaarrrr 2222000000000000 pppprrrroooobbbblllleeeemmmm???? IIIIssss PPPPeeeerrrrllll YYYY2222KKKK ccccoooommmmpppplllliiiiaaaannnntttt????
-
- Short answer: No, Perl does not have a Year 2000 problem.
- Yes, Perl is Y2K compliant. The programmers you're hired to
- use it, however, probably are not.
-
- Long answer: Perl is just as Y2K compliant as your pencil--
- no more, and no less. The date and time functions supplied
- with perl (gmtime and localtime) supply adequate information
- to determine the year well beyond 2000 (2038 is when trouble
- strikes for 32-bit machines). The year returned by these
- functions when used in an array context is the year minus
- 1900. For years between 1910 and 1999 this _h_a_p_p_e_n_s to be a
- 2-digit decimal number. To avoid the year 2000 problem
- simply do not treat the year as a 2-digit number. It isn't.
-
- When _g_m_t_i_m_e() and _l_o_c_a_l_t_i_m_e() are used in scalar context
- they return a timestamp string that contains a fully-
- expanded year. For example, $timestamp = gmtime(1005613200)
- sets $timestamp to "Tue Nov 13 01:00:00 2001". There's no
- year 2000 problem here.
-
- That doesn't mean that Perl can't be used to create non-Y2K
- compliant programs. It can. But so can your pencil. It's
- the fault of the user, not the language. At the risk of
- inflaming the NRA: ``Perl doesn't break Y2K, people do.''
- See http://language.perl.com/news/y2k.html for a longer
- exposition.
-
-
-
-
- Page 5 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- DDDDaaaattttaaaa:::: SSSSttttrrrriiiinnnnggggssss
- HHHHoooowwww ddddoooo IIII vvvvaaaalllliiiiddddaaaatttteeee iiiinnnnppppuuuutttt????
-
- The answer to this question is usually a regular expression,
- perhaps with auxiliary logic. See the more specific
- questions (numbers, mail addresses, etc.) for details.
-
- HHHHoooowwww ddddoooo IIII uuuunnnneeeessssccccaaaappppeeee aaaa ssssttttrrrriiiinnnngggg????
-
- It depends just what you mean by ``escape''. URL escapes
- are dealt with in the _p_e_r_l_f_a_q_9 manpage. Shell escapes with
- the backslash (\) character are removed with:
-
- s/\\(.)/$1/g;
-
- This won't expand "\n" or "\t" or any other special escapes.
-
- HHHHoooowwww ddddoooo IIII rrrreeeemmmmoooovvvveeee ccccoooonnnnsssseeeeccccuuuuttttiiiivvvveeee ppppaaaaiiiirrrrssss ooooffff cccchhhhaaaarrrraaaacccctttteeeerrrrssss????
-
- To turn "abbcccd" into "abccd":
-
- s/(.)\1/$1/g;
-
-
- HHHHoooowwww ddddoooo IIII eeeexxxxppppaaaannnndddd ffffuuuunnnnccccttttiiiioooonnnn ccccaaaallllllllssss iiiinnnn aaaa ssssttttrrrriiiinnnngggg????
-
- This is documented in the _p_e_r_l_r_e_f manpage. In general, this
- is fraught with quoting and readability problems, but it is
- possible. To interpolate a subroutine call (in list
- context) into a string:
-
- print "My sub returned @{[mysub(1,2,3)]} that time.\n";
-
- If you prefer scalar context, similar chicanery is also
- useful for arbitrary expressions:
-
- print "That yields ${\($n + 5)} widgets\n";
-
- Version 5.004 of Perl had a bug that gave list context to
- the expression in ${...}, but this is fixed in version
- 5.005.
-
- See also ``How can I expand variables in text strings?'' in
- this section of the FAQ.
-
- HHHHoooowwww ddddoooo IIII ffffiiiinnnndddd mmmmaaaattttcccchhhhiiiinnnngggg////nnnneeeessssttttiiiinnnngggg aaaannnnyyyytttthhhhiiiinnnngggg????
-
- This isn't something that can be done in one regular
- expression, no matter how complicated. To find something
- between two single characters, a pattern like /x([^x]*)x/
- will get the intervening bits in $1. For multiple ones, then
- something more like /alpha(.*?)omega/ would be needed. But
-
-
-
- Page 6 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- none of these deals with nested patterns, nor can they. For
- that you'll have to write a parser.
-
- If you are serious about writing a parser, there are a
- number of modules or oddities that will make your life a lot
- easier. There is the CPAN module Parse::RecDescent, the
- standard module Text::Balanced, the byacc program, and
- Mark-Jason Dominus's excellent _p_y tool at
- http://www.plover.com/~mjd/perl/py/ .
-
- One simple destructive, inside-out approach that you might
- try is to pull out the smallest nesting parts one at a time:
-
- while (s//BEGIN((?:(?!BEGIN)(?!END).)*)END/gs) {
- # do something with $1
- }
-
-
- HHHHoooowwww ddddoooo IIII rrrreeeevvvveeeerrrrsssseeee aaaa ssssttttrrrriiiinnnngggg????
-
- Use _r_e_v_e_r_s_e() in scalar context, as documented in the
- reverse entry in the _p_e_r_l_f_u_n_c manpage.
-
- $reversed = reverse $string;
-
-
- HHHHoooowwww ddddoooo IIII eeeexxxxppppaaaannnndddd ttttaaaabbbbssss iiiinnnn aaaa ssssttttrrrriiiinnnngggg????
-
- You can do it yourself:
-
- 1 while $string =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e;
-
- Or you can just use the Text::Tabs module (part of the
- standard perl distribution).
-
- use Text::Tabs;
- @expanded_lines = expand(@lines_with_tabs);
-
-
- HHHHoooowwww ddddoooo IIII rrrreeeeffffoooorrrrmmmmaaaatttt aaaa ppppaaaarrrraaaaggggrrrraaaapppphhhh????
-
- Use Text::Wrap (part of the standard perl distribution):
-
- use Text::Wrap;
- print wrap("\t", ' ', @paragraphs);
-
- The paragraphs you give to Text::Wrap should not contain
- embedded newlines. Text::Wrap doesn't justify the lines
- (flush-right).
-
-
-
-
-
-
- Page 7 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- HHHHoooowwww ccccaaaannnn IIII aaaacccccccceeeessssssss////cccchhhhaaaannnnggggeeee tttthhhheeee ffffiiiirrrrsssstttt NNNN lllleeeetttttttteeeerrrrssss ooooffff aaaa ssssttttrrrriiiinnnngggg????
-
- There are many ways. If you just want to grab a copy, use
- _s_u_b_s_t_r():
-
- $first_byte = substr($a, 0, 1);
-
- If you want to modify part of a string, the simplest way is
- often to use _s_u_b_s_t_r() as an lvalue:
-
- substr($a, 0, 3) = "Tom";
-
- Although those with a pattern matching kind of thought
- process will likely prefer:
-
- $a =~ s/^.../Tom/;
-
-
- HHHHoooowwww ddddoooo IIII cccchhhhaaaannnnggggeeee tttthhhheeee NNNNtttthhhh ooooccccccccuuuurrrrrrrreeeennnncccceeee ooooffff ssssoooommmmeeeetttthhhhiiiinnnngggg????
-
- You have to keep track of N yourself. For example, let's
- say you want to change the fifth occurrence of "whoever" or
- "whomever" into "whosoever" or "whomsoever", case
- insensitively.
-
- $count = 0;
- s{((whom?)ever)}{
- ++$count == 5 # is it the 5th?
- ? "${2}soever" # yes, swap
- : $1 # renege and leave it there
- }igex;
-
- In the more general case, you can use the /g modifier in a
- while loop, keeping count of matches.
-
- $WANT = 3;
- $count = 0;
- while (/(\w+)\s+fish\b/gi) {
- if (++$count == $WANT) {
- print "The third fish is a $1 one.\n";
- # Warning: don't `last' out of this loop
- }
- }
-
- That prints out: "The third fish is a red one." You can
- also use a repetition count and repeated pattern like this:
-
- /(?:\w+\s+fish\s+){2}(\w+)\s+fish/i;
-
-
-
-
-
-
-
- Page 8 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- HHHHoooowwww ccccaaaannnn IIII ccccoooouuuunnnntttt tttthhhheeee nnnnuuuummmmbbbbeeeerrrr ooooffff ooooccccccccuuuurrrrrrrreeeennnncccceeeessss ooooffff aaaa ssssuuuubbbbssssttttrrrriiiinnnngggg
- wwwwiiiitttthhhhiiiinnnn aaaa ssssttttrrrriiiinnnngggg????
-
- There are a number of ways, with varying efficiency: If you
- want a count of a certain single character (X) within a
- string, you can use the tr/// function like so:
-
- $string = "ThisXlineXhasXsomeXx'sXinXit":
- $count = ($string =~ tr/X//);
- print "There are $count X charcters in the string";
-
- This is fine if you are just looking for a single character.
- However, if you are trying to count multiple character
- substrings within a larger string, tr/// won't work. What
- you can do is wrap a _w_h_i_l_e() loop around a global pattern
- match. For example, let's count negative integers:
-
- $string = "-9 55 48 -2 23 -76 4 14 -44";
- while ($string =~ /-\d+/g) { $count++ }
- print "There are $count negative numbers in the string";
-
-
- HHHHoooowwww ddddoooo IIII ccccaaaappppiiiittttaaaalllliiiizzzzeeee aaaallllllll tttthhhheeee wwwwoooorrrrddddssss oooonnnn oooonnnneeee lllliiiinnnneeee????
-
- To make the first letter of each word upper case:
-
- $line =~ s/\b(\w)/\U$1/g;
-
- This has the strange effect of turning "don't do it" into
- "Don'T Do It". Sometimes you might want this, instead
- (Suggested by Brian Foy):
-
- $string =~ s/ (
- (^\w) #at the beginning of the line
- | # or
- (\s\w) #preceded by whitespace
- )
- /\U$1/xg;
- $string =~ /([\w']+)/\u\L$1/g;
-
- To make the whole line upper case:
-
- $line = uc($line);
-
- To force each word to be lower case, with the first letter
- upper case:
-
- $line =~ s/(\w+)/\u\L$1/g;
-
- You can (and probably should) enable locale awareness of
- those characters by placing a use locale pragma in your
- program. See the _p_e_r_l_l_o_c_a_l_e manpage for endless details on
-
-
-
- Page 9 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- locales.
-
- HHHHoooowwww ccccaaaannnn IIII sssspppplllliiiitttt aaaa [[[[cccchhhhaaaarrrraaaacccctttteeeerrrr]]]] ddddeeeelllliiiimmmmiiiitttteeeedddd ssssttttrrrriiiinnnngggg eeeexxxxcccceeeepppptttt wwwwhhhheeeennnn
- iiiinnnnssssiiiiddddeeee [[[[cccchhhhaaaarrrraaaacccctttteeeerrrr]]]]???? ((((CCCCoooommmmmmmmaaaa----sssseeeeppppaaaarrrraaaatttteeeedddd ffffiiiilllleeeessss))))
-
- Take the example case of trying to split a string that is
- comma-separated into its different fields. (We'll pretend
- you said comma-separated, not comma-delimited, which is
- different and almost never what you mean.) You can't use
- split(/,/) because you shouldn't split if the comma is
- inside quotes. For example, take a data line like this:
-
- SAR001,"","Cimetrix, Inc","Bob Smith","CAM",N,8,1,0,7,"Error, Core Dumped"
-
- Due to the restriction of the quotes, this is a fairly
- complex problem. Thankfully, we have Jeffrey Friedl, author
- of a highly recommended book on regular expressions, to
- handle these for us. He suggests (assuming your string is
- contained in $text):
-
- @new = ();
- push(@new, $+) while $text =~ m{
- "([^\"\\]*(?:\\.[^\"\\]*)*)",? # groups the phrase inside the quotes
- | ([^,]+),?
- | ,
- }gx;
- push(@new, undef) if substr($text,-1,1) eq ',';
-
- If you want to represent quotation marks inside a
- quotation-mark-delimited field, escape them with backslashes
- (eg, "like \"this\"". Unescaping them is a task addressed
- earlier in this section.
-
- Alternatively, the Text::ParseWords module (part of the
- standard perl distribution) lets you say:
-
- use Text::ParseWords;
- @new = quotewords(",", 0, $text);
-
-
- HHHHoooowwww ddddoooo IIII ssssttttrrrriiiipppp bbbbllllaaaannnnkkkk ssssppppaaaacccceeee ffffrrrroooommmm tttthhhheeee bbbbeeeeggggiiiinnnnnnnniiiinnnngggg////eeeennnndddd ooooffff aaaa
- ssssttttrrrriiiinnnngggg????
-
- Although the simplest approach would seem to be:
-
- $string =~ s/^\s*(.*?)\s*$/$1/;
-
- This is unneccesarily slow, destructive, and fails with
- embedded newlines. It is much better faster to do this in
- two steps:
-
-
-
-
-
- Page 10 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- $string =~ s/^\s+//;
- $string =~ s/\s+$//;
-
- Or more nicely written as:
-
- for ($string) {
- s/^\s+//;
- s/\s+$//;
- }
-
- This idiom takes advantage of the foreach loop's aliasing
- behavior to factor out common code. You can do this on
- several strings at once, or arrays, or even the values of a
- hash if you use a slide:
-
- # trim whitespace in the scalar, the array,
- # and all the values in the hash
- foreach ($scalar, @array, @hash{keys %hash}) {
- s/^\s+//;
- s/\s+$//;
- }
-
-
- HHHHoooowwww ddddoooo IIII eeeexxxxttttrrrraaaacccctttt sssseeeelllleeeecccctttteeeedddd ccccoooolllluuuummmmnnnnssss ffffrrrroooommmm aaaa ssssttttrrrriiiinnnngggg????
-
- Use _s_u_b_s_t_r() or _u_n_p_a_c_k(), both documented in the _p_e_r_l_f_u_n_c
- manpage. If you prefer thinking in terms of columns instead
- of widths, you can use this kind of thing:
-
- # determine the unpack format needed to split Linux ps output
- # arguments are cut columns
- my $fmt = cut2fmt(8, 14, 20, 26, 30, 34, 41, 47, 59, 63, 67, 72);
-
- sub cut2fmt {
- my(@positions) = @_;
- my $template = '';
- my $lastpos = 1;
- for my $place (@positions) {
- $template .= "A" . ($place - $lastpos) . " ";
- $lastpos = $place;
- }
- $template .= "A*";
- return $template;
- }
-
-
- HHHHoooowwww ddddoooo IIII ffffiiiinnnndddd tttthhhheeee ssssoooouuuunnnnddddeeeexxxx vvvvaaaalllluuuueeee ooooffff aaaa ssssttttrrrriiiinnnngggg????
-
- Use the standard Text::Soundex module distributed with perl.
-
-
-
-
-
-
- Page 11 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- HHHHoooowwww ccccaaaannnn IIII eeeexxxxppppaaaannnndddd vvvvaaaarrrriiiiaaaabbbblllleeeessss iiiinnnn tttteeeexxxxtttt ssssttttrrrriiiinnnnggggssss????
-
- Let's assume that you have a string like:
-
- $text = 'this has a $foo in it and a $bar';
-
- If those were both global variables, then this would
- suffice:
-
- $text =~ s/\$(\w+)/${$1}/g;
-
- But since they are probably lexicals, or at least, they
- could be, you'd have to do this:
-
- $text =~ s/(\$\w+)/$1/eeg;
- die if $@; # needed on /ee, not /e
-
- It's probably better in the general case to treat those
- variables as entries in some special hash. For example:
-
- %user_defs = (
- foo => 23,
- bar => 19,
- );
- $text =~ s/\$(\w+)/$user_defs{$1}/g;
-
- See also ``How do I expand function calls in a string?'' in
- this section of the FAQ.
-
- WWWWhhhhaaaatttt''''ssss wwwwrrrroooonnnngggg wwwwiiiitttthhhh aaaallllwwwwaaaayyyyssss qqqquuuuoooottttiiiinnnngggg """"$$$$vvvvaaaarrrrssss""""????
-
- The problem is that those double-quotes force
- stringification, coercing numbers and references into
- strings, even when you don't want them to be.
-
- If you get used to writing odd things like these:
-
- print "$var"; # BAD
- $new = "$old"; # BAD
- somefunc("$var"); # BAD
-
- You'll be in trouble. Those should (in 99.8% of the cases)
- be the simpler and more direct:
-
- print $var;
- $new = $old;
- somefunc($var);
-
- Otherwise, besides slowing you down, you're going to break
- code when the thing in the scalar is actually neither a
- string nor a number, but a reference:
-
-
-
-
- Page 12 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- func(\@array);
- sub func {
- my $aref = shift;
- my $oref = "$aref"; # WRONG
- }
-
- You can also get into subtle problems on those few
- operations in Perl that actually do care about the
- difference between a string and a number, such as the
- magical ++ autoincrement operator or the _s_y_s_c_a_l_l() function.
-
- Stringification also destroys arrays.
-
- @lines = `command`;
- print "@lines"; # WRONG - extra blanks
- print @lines; # right
-
-
- WWWWhhhhyyyy ddddoooonnnn''''tttt mmmmyyyy <<<<<<<<HHHHEEEERRRREEEE ddddooooccccuuuummmmeeeennnnttttssss wwwwoooorrrrkkkk????
-
- Check for these three things:
-
- 1. There must be no space after the << part.
-
- 2. There (probably) should be a semicolon at the end.
-
- 3. You can't (easily) have any space in front of the tag.
-
- If you want to indent the text in the here document, you can
- do this:
-
- # all in one
- ($VAR = <<HERE_TARGET) =~ s/^\s+//gm;
- your text
- goes here
- HERE_TARGET
-
- But the HERE_TARGET must still be flush against the margin.
- If you want that indented also, you'll have to quote in the
- indentation.
-
- ($quote = <<' FINIS') =~ s/^\s+//gm;
- ...we will have peace, when you and all your works have
- perished--and the works of your dark master to whom you
- would deliver us. You are a liar, Saruman, and a corrupter
- of men's hearts. --Theoden in /usr/src/perl/taint.c
- FINIS
- $quote =~ s/\s*--/\n--/;
-
- A nice general-purpose fixer-upper function for indented
- here documents follows. It expects to be called with a here
- document as its argument. It looks to see whether each line
-
-
-
- Page 13 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- begins with a common substring, and if so, strips that off.
- Otherwise, it takes the amount of leading white space found
- on the first line and removes that much off each subsequent
- line.
-
- sub fix {
- local $_ = shift;
- my ($white, $leader); # common white space and common leading string
- if (/^\s*(?:([^\w\s]+)(\s*).*\n)(?:\s*\1\2?.*\n)+$/) {
- ($white, $leader) = ($2, quotemeta($1));
- } else {
- ($white, $leader) = (/^(\s+)/, '');
- }
- s/^\s*?$leader(?:$white)?//gm;
- return $_;
- }
-
- This works with leading special strings, dynamically
- determined:
-
- $remember_the_main = fix<<' MAIN_INTERPRETER_LOOP';
- @@@ int
- @@@ runops() {
- @@@ SAVEI32(runlevel);
- @@@ runlevel++;
- @@@ while ( op = (*op->op_ppaddr)() ) ;
- @@@ TAINT_NOT;
- @@@ return 0;
- @@@ }
- MAIN_INTERPRETER_LOOP
-
- Or with a fixed amount of leading white space, with
- remaining indentation correctly preserved:
-
- $poem = fix<<EVER_ON_AND_ON;
- Now far ahead the Road has gone,
- And I must follow, if I can,
- Pursuing it with eager feet,
- Until it joins some larger way
- Where many paths and errands meet.
- And whither then? I cannot say.
- --Bilbo in /usr/src/perl/pp_ctl.c
- EVER_ON_AND_ON
-
-
- DDDDaaaattttaaaa:::: AAAArrrrrrrraaaayyyyssss
- WWWWhhhhaaaatttt iiiissss tttthhhheeee ddddiiiiffffffffeeeerrrreeeennnncccceeee bbbbeeeettttwwwweeeeeeeennnn $$$$aaaarrrrrrrraaaayyyy[1] and @array[1]?
-
- The former is a scalar value, the latter an array slice,
- which makes it a list with one (scalar) value. You should
- use $ when you want a scalar value (most of the time) and @
- when you want a list with one scalar value in it (very, very
-
-
-
- Page 14 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- rarely; nearly never, in fact).
-
- Sometimes it doesn't make a difference, but sometimes it
- does. For example, compare:
-
- $good[0] = `some program that outputs several lines`;
-
- with
-
- @bad[0] = `same program that outputs several lines`;
-
- The ----wwww flag will warn you about these matters.
-
- HHHHoooowwww ccccaaaannnn IIII eeeexxxxttttrrrraaaacccctttt jjjjuuuusssstttt tttthhhheeee uuuunnnniiiiqqqquuuueeee eeeelllleeeemmmmeeeennnnttttssss ooooffff aaaannnn aaaarrrrrrrraaaayyyy????
-
- There are several possible ways, depending on whether the
- array is ordered and whether you wish to preserve the
- ordering.
-
- assumes all true values in the array)
- a) If @in is sorted, and you want @out to be sorted: (this
-
- $prev = 'nonesuch';
- @out = grep($_ ne $prev && ($prev = $_), @in);
-
- This is nice in that it doesn't use much extra memory,
- simulating _u_n_i_q(1)'s behavior of removing only adjacent
- duplicates. It's less nice in that it won't work with
- false values like undef, 0, or ""; "0 but true" is ok,
- though.
-
- b) If you don't know whether @in is sorted:
-
- undef %saw;
- @out = grep(!$saw{$_}++, @in);
-
-
- c) Like (b), but @in contains only small integers:
-
- @out = grep(!$saw[$_]++, @in);
-
-
- d) A way to do (b) without any loops or greps:
-
- undef %saw;
- @saw{@in} = ();
- @out = sort keys %saw; # remove sort if undesired
-
-
- e) Like (d), but @in contains only small positive integers:
-
-
-
-
-
- Page 15 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- undef @ary;
- @ary[@in] = @in;
- @out = @ary;
-
-
- HHHHoooowwww ccccaaaannnn IIII tttteeeellllllll wwwwhhhheeeetttthhhheeeerrrr aaaa lllliiiisssstttt oooorrrr aaaarrrrrrrraaaayyyy ccccoooonnnnttttaaaaiiiinnnnssss aaaa cccceeeerrrrttttaaaaiiiinnnn
- eeeelllleeeemmmmeeeennnntttt????
-
- Hearing the word "in" is an _i_ndication that you probably
- should have used a hash, not a list or array, to store your
- data. Hashes are designed to answer this question quickly
- and efficiently. Arrays aren't.
-
- That being said, there are several ways to approach this.
- If you are going to make this query many times over
- arbitrary string values, the fastest way is probably to
- invert the original array and keep an associative array
- lying about whose keys are the first array's values.
-
- @blues = qw/azure cerulean teal turquoise lapis-lazuli/;
- undef %is_blue;
- for (@blues) { $is_blue{$_} = 1 }
-
- Now you can check whether $is_blue{$some_color}. It might
- have been a good idea to keep the blues all in a hash in the
- first place.
-
- If the values are all small integers, you could use a simple
- indexed array. This kind of an array will take up less
- space:
-
- @primes = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31);
- undef @is_tiny_prime;
- for (@primes) { $is_tiny_prime[$_] = 1; }
-
- Now you check whether $is_tiny_prime[$some_number].
-
- If the values in question are integers instead of strings,
- you can save quite a lot of space by using bit strings
- instead:
-
- @articles = ( 1..10, 150..2000, 2017 );
- undef $read;
- for (@articles) { vec($read,$_,1) = 1 }
-
- Now check whether vec($read,$n,1) is true for some $n.
-
- Please do not use
-
- $is_there = grep $_ eq $whatever, @array;
-
- or worse yet
-
-
-
- Page 16 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- $is_there = grep /$whatever/, @array;
-
- These are slow (checks every element even if the first
- matches), inefficient (same reason), and potentially buggy
- (what if there are regexp characters in $whatever?).
-
- HHHHoooowwww ddddoooo IIII ccccoooommmmppppuuuutttteeee tttthhhheeee ddddiiiiffffffffeeeerrrreeeennnncccceeee ooooffff ttttwwwwoooo aaaarrrrrrrraaaayyyyssss???? HHHHoooowwww ddddoooo IIII
- ccccoooommmmppppuuuutttteeee tttthhhheeee iiiinnnntttteeeerrrrsssseeeeccccttttiiiioooonnnn ooooffff ttttwwwwoooo aaaarrrrrrrraaaayyyyssss????
-
- Use a hash. Here's code to do both and more. It assumes
- that each element is unique in a given array:
-
- @union = @intersection = @difference = ();
- %count = ();
- foreach $element (@array1, @array2) { $count{$element}++ }
- foreach $element (keys %count) {
- push @union, $element;
- push @{ $count{$element} > 1 ? \@intersection : \@difference }, $element;
- }
-
-
- HHHHoooowwww ddddoooo IIII ffffiiiinnnndddd tttthhhheeee ffffiiiirrrrsssstttt aaaarrrrrrrraaaayyyy eeeelllleeeemmmmeeeennnntttt ffffoooorrrr wwwwhhhhiiiicccchhhh aaaa ccccoooonnnnddddiiiittttiiiioooonnnn
- iiiissss ttttrrrruuuueeee????
-
- You can use this if you care about the index:
-
- for ($i=0; $i < @array; $i++) {
- if ($array[$i] eq "Waldo") {
- $found_index = $i;
- last;
- }
- }
-
- Now $found_index has what you want.
-
- HHHHoooowwww ddddoooo IIII hhhhaaaannnnddddlllleeee lllliiiinnnnkkkkeeeedddd lllliiiissssttttssss????
-
- In general, you usually don't need a linked list in Perl,
- since with regular arrays, you can push and pop or shift and
- unshift at either end, or you can use splice to add and/or
- remove arbitrary number of elements at arbitrary points.
- Both pop and shift are both _O(1) operations on perl's
- dynamic arrays. In the absence of shifts and pops, push in
- general needs to reallocate on the order every _l_o_g(N) times,
- and unshift will need to copy pointers each time.
-
- If you really, really wanted, you could use structures as
- described in the _p_e_r_l_d_s_c manpage or the _p_e_r_l_t_o_o_t manpage and
- do just what the algorithm book tells you to do.
-
-
-
-
-
-
- Page 17 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- HHHHoooowwww ddddoooo IIII hhhhaaaannnnddddlllleeee cccciiiirrrrccccuuuullllaaaarrrr lllliiiissssttttssss????
-
- Circular lists could be handled in the traditional fashion
- with linked lists, or you could just do something like this
- with an array:
-
- unshift(@array, pop(@array)); # the last shall be first
- push(@array, shift(@array)); # and vice versa
-
-
- HHHHoooowwww ddddoooo IIII sssshhhhuuuufffffffflllleeee aaaannnn aaaarrrrrrrraaaayyyy rrrraaaannnnddddoooommmmllllyyyy????
-
- Use this:
-
- # fisher_yates_shuffle( \@array ) :
- # generate a random permutation of @array in place
- sub fisher_yates_shuffle {
- my $array = shift;
- my $i;
- for ($i = @$array; --$i; ) {
- my $j = int rand ($i+1);
- next if $i == $j;
- @$array[$i,$j] = @$array[$j,$i];
- }
- }
-
- fisher_yates_shuffle( \@array ); # permutes @array in place
-
- You've probably seen shuffling algorithms that works using
- splice, randomly picking another element to swap the current
- element with:
-
- srand;
- @new = ();
- @old = 1 .. 10; # just a demo
- while (@old) {
- push(@new, splice(@old, rand @old, 1));
- }
-
- This is bad because splice is already _O(N), and since you do
- it N times, you just invented a quadratic algorithm; that
- is, _O(N**2). This does not scale, although Perl is so
- efficient that you probably won't notice this until you have
- rather largish arrays.
-
- HHHHoooowwww ddddoooo IIII pppprrrroooocccceeeessssssss////mmmmooooddddiiiiffffyyyy eeeeaaaacccchhhh eeeelllleeeemmmmeeeennnntttt ooooffff aaaannnn aaaarrrrrrrraaaayyyy????
-
- Use for/foreach:
-
-
-
-
-
-
-
- Page 18 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- for (@lines) {
- s/foo/bar/; # change that word
- y/XZ/ZX/; # swap those letters
- }
-
- Here's another; let's compute spherical volumes:
-
- for (@volumes = @radii) { # @volumes has changed parts
- $_ **= 3;
- $_ *= (4/3) * 3.14159; # this will be constant folded
- }
-
- If you want to do the same thing to modify the values of the
- hash, you may not use the values function, oddly enough.
- You need a slice:
-
- for $orbit ( @orbits{keys %orbits} ) {
- ($orbit **= 3) *= (4/3) * 3.14159;
- }
-
-
- HHHHoooowwww ddddoooo IIII sssseeeelllleeeecccctttt aaaa rrrraaaannnnddddoooommmm eeeelllleeeemmmmeeeennnntttt ffffrrrroooommmm aaaannnn aaaarrrrrrrraaaayyyy????
-
- Use the _r_a_n_d() function (see the rand entry in the _p_e_r_l_f_u_n_c
- manpage):
-
- # at the top of the program:
- srand; # not needed for 5.004 and later
-
- # then later on
- $index = rand @array;
- $element = $array[$index];
-
- Make sure you _o_n_l_y _c_a_l_l _s_r_a_n_d _o_n_c_e _p_e_r _p_r_o_g_r_a_m, _i_f _t_h_e_n. If
- you are calling it more than once (such as before each call
- to rand), you're almost certainly doing something wrong.
-
- HHHHoooowwww ddddoooo IIII ppppeeeerrrrmmmmuuuutttteeee NNNN eeeelllleeeemmmmeeeennnnttttssss ooooffff aaaa lllliiiisssstttt????
-
- Here's a little program that generates all permutations of
- all the words on each line of input. The algorithm embodied
- in the _p_e_r_m_u_t_e() function should work on any list:
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 19 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- #!/usr/bin/perl -n
- # tsc-permute: permute each word of input
- permute([split], []);
- sub permute {
- my @items = @{ $_[0] };
- my @perms = @{ $_[1] };
- unless (@items) {
- print "@perms\n";
- } else {
- my(@newitems,@newperms,$i);
- foreach $i (0 .. $#items) {
- @newitems = @items;
- @newperms = @perms;
- unshift(@newperms, splice(@newitems, $i, 1));
- permute([@newitems], [@newperms]);
- }
- }
- }
-
-
- HHHHoooowwww ddddoooo IIII ssssoooorrrrtttt aaaannnn aaaarrrrrrrraaaayyyy bbbbyyyy ((((aaaannnnyyyytttthhhhiiiinnnngggg))))????
-
- Supply a comparison function to _s_o_r_t() (described in the
- sort entry in the _p_e_r_l_f_u_n_c manpage):
-
- @list = sort { $a <=> $b } @list;
-
- The default sort function is cmp, string comparison, which
- would sort (1, 2, 10) into (1, 10, 2). <=>, used above, is
- the numerical comparison operator.
-
- If you have a complicated function needed to pull out the
- part you want to sort on, then don't do it inside the sort
- function. Pull it out first, because the sort BLOCK can be
- called many times for the same element. Here's an example
- of how to pull out the first word after the first number on
- each item, and then sort those words case-insensitively.
-
- @idx = ();
- for (@data) {
- ($item) = /\d+\s*(\S+)/;
- push @idx, uc($item);
- }
- @sorted = @data[ sort { $idx[$a] cmp $idx[$b] } 0 .. $#idx ];
-
- Which could also be written this way, using a trick that's
- come to be known as the Schwartzian Transform:
-
- @sorted = map { $_->[0] }
- sort { $a->[1] cmp $b->[1] }
- map { [ $_, uc((/\d+\s*(\S+)/ )[0] ] } @data;
-
-
-
-
- Page 20 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- If you need to sort on several fields, the following
- paradigm is useful.
-
- @sorted = sort { field1($a) <=> field1($b) ||
- field2($a) cmp field2($b) ||
- field3($a) cmp field3($b)
- } @data;
-
- This can be conveniently combined with precalculation of
- keys as given above.
-
- See http://www.perl.com/CPAN/doc/FMTEYEWTK/sort.html for
- more about this approach.
-
- See also the question below on sorting hashes.
-
- HHHHoooowwww ddddoooo IIII mmmmaaaannnniiiippppuuuullllaaaatttteeee aaaarrrrrrrraaaayyyyssss ooooffff bbbbiiiittttssss????
-
- Use _p_a_c_k() and _u_n_p_a_c_k(), or else _v_e_c() and the bitwise
- operations.
-
- For example, this sets $vec to have bit N set if $ints[N]
- was set:
-
- $vec = '';
- foreach(@ints) { vec($vec,$_,1) = 1 }
-
- And here's how, given a vector in $vec, you can get those
- bits into your @ints array:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 21 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- sub bitvec_to_list {
- my $vec = shift;
- my @ints;
- # Find null-byte density then select best algorithm
- if ($vec =~ tr/\0// / length $vec > 0.95) {
- use integer;
- my $i;
- # This method is faster with mostly null-bytes
- while($vec =~ /[^\0]/g ) {
- $i = -9 + 8 * pos $vec;
- push @ints, $i if vec($vec, ++$i, 1);
- push @ints, $i if vec($vec, ++$i, 1);
- push @ints, $i if vec($vec, ++$i, 1);
- push @ints, $i if vec($vec, ++$i, 1);
- push @ints, $i if vec($vec, ++$i, 1);
- push @ints, $i if vec($vec, ++$i, 1);
- push @ints, $i if vec($vec, ++$i, 1);
- push @ints, $i if vec($vec, ++$i, 1);
- }
- } else {
- # This method is a fast general algorithm
- use integer;
- my $bits = unpack "b*", $vec;
- push @ints, 0 if $bits =~ s/^(\d)// && $1;
- push @ints, pos $bits while($bits =~ /1/g);
- }
- return \@ints;
- }
-
- This method gets faster the more sparse the bit vector is.
- (Courtesy of Tim Bunce and Winfried Koenig.)
-
- WWWWhhhhyyyy ddddooooeeeessss _d_e_f_i_n_e_d() return true on empty arrays and hashes?
-
- See the defined entry in the _p_e_r_l_f_u_n_c manpage in the 5.004
- release or later of Perl.
-
- DDDDaaaattttaaaa:::: HHHHaaaasssshhhheeeessss ((((AAAAssssssssoooocccciiiiaaaattttiiiivvvveeee AAAArrrrrrrraaaayyyyssss))))
- HHHHoooowwww ddddoooo IIII pppprrrroooocccceeeessssssss aaaannnn eeeennnnttttiiiirrrreeee hhhhaaaasssshhhh????
-
- Use the _e_a_c_h() function (see the each entry in the _p_e_r_l_f_u_n_c
- manpage) if you don't care whether it's sorted:
-
- while ( ($key, $value) = each %hash) {
- print "$key = $value\n";
- }
-
- If you want it sorted, you'll have to use _f_o_r_e_a_c_h() on the
- result of sorting the keys as shown in an earlier question.
-
-
-
-
-
-
- Page 22 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- WWWWhhhhaaaatttt hhhhaaaappppppppeeeennnnssss iiiiffff IIII aaaadddddddd oooorrrr rrrreeeemmmmoooovvvveeee kkkkeeeeyyyyssss ffffrrrroooommmm aaaa hhhhaaaasssshhhh wwwwhhhhiiiilllleeee
- iiiitttteeeerrrraaaattttiiiinnnngggg oooovvvveeeerrrr iiiitttt????
-
- Don't do that.
-
- HHHHoooowwww ddddoooo IIII llllooooooookkkk uuuupppp aaaa hhhhaaaasssshhhh eeeelllleeeemmmmeeeennnntttt bbbbyyyy vvvvaaaalllluuuueeee????
-
- Create a reverse hash:
-
- %by_value = reverse %by_key;
- $key = $by_value{$value};
-
- That's not particularly efficient. It would be more space-
- efficient to use:
-
- while (($key, $value) = each %by_key) {
- $by_value{$value} = $key;
- }
-
- If your hash could have repeated values, the methods above
- will only find one of the associated keys. This may or may
- not worry you.
-
- HHHHoooowwww ccccaaaannnn IIII kkkknnnnoooowwww hhhhoooowwww mmmmaaaannnnyyyy eeeennnnttttrrrriiiieeeessss aaaarrrreeee iiiinnnn aaaa hhhhaaaasssshhhh????
-
- If you mean how many keys, then all you have to do is take
- the scalar sense of the _k_e_y_s() function:
-
- $num_keys = scalar keys %hash;
-
- In void context it just resets the iterator, which is faster
- for tied hashes.
-
- HHHHoooowwww ddddoooo IIII ssssoooorrrrtttt aaaa hhhhaaaasssshhhh ((((ooooppppttttiiiioooonnnnaaaallllllllyyyy bbbbyyyy vvvvaaaalllluuuueeee iiiinnnnsssstttteeeeaaaadddd ooooffff kkkkeeeeyyyy))))????
-
- Internally, hashes are stored in a way that prevents you
- from imposing an order on key-value pairs. Instead, you
- have to sort a list of the keys or values:
-
- @keys = sort keys %hash; # sorted by key
- @keys = sort {
- $hash{$a} cmp $hash{$b}
- } keys %hash; # and by value
-
- Here we'll do a reverse numeric sort by value, and if two
- keys are identical, sort by length of key, and if that
- fails, by straight ASCII comparison of the keys (well,
- possibly modified by your locale -- see the _p_e_r_l_l_o_c_a_l_e
- manpage).
-
-
-
-
-
-
- Page 23 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- @keys = sort {
- $hash{$b} <=> $hash{$a}
- ||
- length($b) <=> length($a)
- ||
- $a cmp $b
- } keys %hash;
-
-
- HHHHoooowwww ccccaaaannnn IIII aaaallllwwwwaaaayyyyssss kkkkeeeeeeeepppp mmmmyyyy hhhhaaaasssshhhh ssssoooorrrrtttteeeedddd????
-
- You can look into using the DB_File module and _t_i_e() using
- the $DB_BTREE hash bindings as documented in the section on
- _I_n _M_e_m_o_r_y _D_a_t_a_b_a_s_e_s in the _D_B__F_i_l_e manpage. The Tie::IxHash
- module from CPAN might also be instructive.
-
- WWWWhhhhaaaatttt''''ssss tttthhhheeee ddddiiiiffffffffeeeerrrreeeennnncccceeee bbbbeeeettttwwwweeeeeeeennnn """"ddddeeeelllleeeetttteeee"""" aaaannnndddd """"uuuunnnnddddeeeeffff"""" wwwwiiiitttthhhh
- hhhhaaaasssshhhheeeessss????
-
- Hashes are pairs of scalars: the first is the key, the
- second is the value. The key will be coerced to a string,
- although the value can be any kind of scalar: string,
- number, or reference. If a key $key is present in the
- array, exists($key) will return true. The value for a given
- key can be undef, in which case $array{$key} will be undef
- while $exists{$key} will return true. This corresponds to
- ($key, undef) being in the hash.
-
- Pictures help... here's the %ary table:
-
- keys values
- +------+------+
- | a | 3 |
- | x | 7 |
- | d | 0 |
- | e | 2 |
- +------+------+
-
- And these conditions hold
-
- $ary{'a'} is true
- $ary{'d'} is false
- defined $ary{'d'} is true
- defined $ary{'a'} is true
- exists $ary{'a'} is true (perl5 only)
- grep ($_ eq 'a', keys %ary) is true
-
- If you now say
-
- undef $ary{'a'}
-
- your table now reads:
-
-
-
- Page 24 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- keys values
- +------+------+
- | a | undef|
- | x | 7 |
- | d | 0 |
- | e | 2 |
- +------+------+
-
- and these conditions now hold; changes in caps:
-
- $ary{'a'} is FALSE
- $ary{'d'} is false
- defined $ary{'d'} is true
- defined $ary{'a'} is FALSE
- exists $ary{'a'} is true (perl5 only)
- grep ($_ eq 'a', keys %ary) is true
-
- Notice the last two: you have an undef value, but a defined
- key!
-
- Now, consider this:
-
- delete $ary{'a'}
-
- your table now reads:
-
- keys values
- +------+------+
- | x | 7 |
- | d | 0 |
- | e | 2 |
- +------+------+
-
- and these conditions now hold; changes in caps:
-
- $ary{'a'} is false
- $ary{'d'} is false
- defined $ary{'d'} is true
- defined $ary{'a'} is false
- exists $ary{'a'} is FALSE (perl5 only)
- grep ($_ eq 'a', keys %ary) is FALSE
-
- See, the whole entry is gone!
-
- WWWWhhhhyyyy ddddoooonnnn''''tttt mmmmyyyy ttttiiiieeeedddd hhhhaaaasssshhhheeeessss mmmmaaaakkkkeeee tttthhhheeee ddddeeeeffffiiiinnnneeeedddd////eeeexxxxiiiissssttttssss
- ddddiiiissssttttiiiinnnnccccttttiiiioooonnnn????
-
- They may or may not implement the _E_X_I_S_T_S() and _D_E_F_I_N_E_D()
- methods differently. For example, there isn't the concept
- of undef with hashes that are tied to DBM* files. This means
- the true/false tables above will give different results when
- used on such a hash. It also means that exists and defined
-
-
-
- Page 25 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- do the same thing with a DBM* file, and what they end up
- doing is not what they do with ordinary hashes.
-
- HHHHoooowwww ddddoooo IIII rrrreeeesssseeeetttt aaaannnn _e_a_c_h() operation part-way through?
-
- Using keys %hash in scalar context returns the number of
- keys in the hash _a_n_d resets the iterator associated with the
- hash. You may need to do this if you use last to exit a
- loop early so that when you re-enter it, the hash iterator
- has been reset.
-
- HHHHoooowwww ccccaaaannnn IIII ggggeeeetttt tttthhhheeee uuuunnnniiiiqqqquuuueeee kkkkeeeeyyyyssss ffffrrrroooommmm ttttwwwwoooo hhhhaaaasssshhhheeeessss????
-
- First you extract the keys from the hashes into arrays, and
- then solve the uniquifying the array problem described
- above. For example:
-
- %seen = ();
- for $element (keys(%foo), keys(%bar)) {
- $seen{$element}++;
- }
- @uniq = keys %seen;
-
- Or more succinctly:
-
- @uniq = keys %{{%foo,%bar}};
-
- Or if you really want to save space:
-
- %seen = ();
- while (defined ($key = each %foo)) {
- $seen{$key}++;
- }
- while (defined ($key = each %bar)) {
- $seen{$key}++;
- }
- @uniq = keys %seen;
-
-
- HHHHoooowwww ccccaaaannnn IIII ssssttttoooorrrreeee aaaa mmmmuuuullllttttiiiiddddiiiimmmmeeeennnnssssiiiioooonnnnaaaallll aaaarrrrrrrraaaayyyy iiiinnnn aaaa DDDDBBBBMMMM ffffiiiilllleeee????
-
- Either stringify the structure yourself (no fun), or else
- get the MLDBM (which uses Data::Dumper) module from CPAN and
- layer it on top of either DB_File or GDBM_File.
-
- HHHHoooowwww ccccaaaannnn IIII mmmmaaaakkkkeeee mmmmyyyy hhhhaaaasssshhhh rrrreeeemmmmeeeemmmmbbbbeeeerrrr tttthhhheeee oooorrrrddddeeeerrrr IIII ppppuuuutttt eeeelllleeeemmmmeeeennnnttttssss
- iiiinnnnttttoooo iiiitttt????
-
- Use the Tie::IxHash from CPAN.
-
-
-
-
-
-
- Page 26 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- use Tie::IxHash;
- tie(%myhash, Tie::IxHash);
- for ($i=0; $i<20; $i++) {
- $myhash{$i} = 2*$i;
- }
- @keys = keys %myhash;
- # @keys = (0,1,2,3,...)
-
-
- WWWWhhhhyyyy ddddooooeeeessss ppppaaaassssssssiiiinnnngggg aaaa ssssuuuubbbbrrrroooouuuuttttiiiinnnneeee aaaannnn uuuunnnnddddeeeeffffiiiinnnneeeedddd eeeelllleeeemmmmeeeennnntttt iiiinnnn aaaa hhhhaaaasssshhhh
- ccccrrrreeeeaaaatttteeee iiiitttt????
-
- If you say something like:
-
- somefunc($hash{"nonesuch key here"});
-
- Then that element "autovivifies"; that is, it springs into
- existence whether you store something there or not. That's
- because functions get scalars passed in by reference. If
- _s_o_m_e_f_u_n_c() modifies $_[0], it has to be ready to write it
- back into the caller's version.
-
- This has been fixed as of perl5.004.
-
- Normally, merely accessing a key's value for a nonexistent
- key does _n_o_t cause that key to be forever there. This is
- different than awk's behavior.
-
- HHHHoooowwww ccccaaaannnn IIII mmmmaaaakkkkeeee tttthhhheeee PPPPeeeerrrrllll eeeeqqqquuuuiiiivvvvaaaalllleeeennnntttt ooooffff aaaa CCCC ssssttttrrrruuuuccccttttuuuurrrreeee////CCCC++++++++
- ccccllllaaaassssssss////hhhhaaaasssshhhh oooorrrr aaaarrrrrrrraaaayyyy ooooffff hhhhaaaasssshhhheeeessss oooorrrr aaaarrrrrrrraaaayyyyssss????
-
- Use references (documented in the _p_e_r_l_r_e_f manpage).
- Examples of complex data structures are given in the _p_e_r_l_d_s_c
- manpage and the _p_e_r_l_l_o_l manpage. Examples of structures and
- object-oriented classes are in the _p_e_r_l_t_o_o_t manpage.
-
- HHHHoooowwww ccccaaaannnn IIII uuuusssseeee aaaa rrrreeeeffffeeeerrrreeeennnncccceeee aaaassss aaaa hhhhaaaasssshhhh kkkkeeeeyyyy????
-
- You can't do this directly, but you could use the standard
- Tie::Refhash module distributed with perl.
-
- DDDDaaaattttaaaa:::: MMMMiiiisssscccc
- HHHHoooowwww ddddoooo IIII hhhhaaaannnnddddlllleeee bbbbiiiinnnnaaaarrrryyyy ddddaaaattttaaaa ccccoooorrrrrrrreeeeccccttttllllyyyy????
-
- Perl is binary clean, so this shouldn't be a problem. For
- example, this works fine (assuming the files are found):
-
- if (`cat /vmunix` =~ /gzip/) {
- print "Your kernel is GNU-zip enabled!\n";
- }
-
- On some systems, however, you have to play tedious games
-
-
-
- Page 27 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- with "text" versus "binary" files. See the section on
- _b_i_n_m_o_d_e in the _p_e_r_l_f_u_n_c manpage.
-
- If you're concerned about 8-bit ASCII data, then see the
- _p_e_r_l_l_o_c_a_l_e manpage.
-
- If you want to deal with multibyte characters, however,
- there are some gotchas. See the section on Regular
- Expressions.
-
- HHHHoooowwww ddddoooo IIII ddddeeeetttteeeerrrrmmmmiiiinnnneeee wwwwhhhheeeetttthhhheeeerrrr aaaa ssssccccaaaallllaaaarrrr iiiissss aaaa
- nnnnuuuummmmbbbbeeeerrrr////wwwwhhhhoooolllleeee////iiiinnnntttteeeeggggeeeerrrr////ffffllllooooaaaatttt????
-
- Assuming that you don't care about IEEE notations like "NaN"
- or "Infinity", you probably just want to use a regular
- expression.
-
- warn "has nondigits" if /\D/;
- warn "not a natural number" unless /^\d+$/; # rejects -3
- warn "not an integer" unless /^-?\d+$/; # rejects +3
- warn "not an integer" unless /^[+-]?\d+$/;
- warn "not a decimal number" unless /^-?\d+\.?\d*$/; # rejects .2
- warn "not a decimal number" unless /^-?(?:\d+(?:\.\d*)?|\.\d+)$/;
- warn "not a C float"
- unless /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/;
-
- If you're on a POSIX system, Perl's supports the
- POSIX::strtod function. Its semantics are somewhat
- cumbersome, so here's a getnum wrapper function for more
- convenient access. This function takes a string and returns
- the number it found, or undef for input that isn't a C
- float. The is_numeric function is a front end to getnum if
- you just want to say, ``Is this a float?''
-
- sub getnum {
- use POSIX qw(strtod);
- my $str = shift;
- $str =~ s/^\s+//;
- $str =~ s/\s+$//;
- $! = 0;
- my($num, $unparsed) = strtod($str);
- if (($str eq '') || ($unparsed != 0) || $!) {
- return undef;
- } else {
- return $num;
- }
- }
-
- sub is_numeric { defined &getnum }
-
- Or you could check out http://www.perl.com/CPAN/modules/by-
- module/String/String-Scanf-1.1.tar.gz instead. The POSIX
-
-
-
- Page 28 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
- module (part of the standard Perl distribution) provides the
- strtol and strtod for converting strings to double and
- longs, respectively.
-
- HHHHoooowwww ddddoooo IIII kkkkeeeeeeeepppp ppppeeeerrrrssssiiiisssstttteeeennnntttt ddddaaaattttaaaa aaaaccccrrrroooossssssss pppprrrrooooggggrrrraaaammmm ccccaaaallllllllssss????
-
- For some specific applications, you can use one of the DBM
- modules. See the _A_n_y_D_B_M__F_i_l_e manpage. More generically,
- you should consult the FreezeThaw, Storable, or Class::Eroot
- modules from CPAN.
-
- HHHHoooowwww ddddoooo IIII pppprrrriiiinnnntttt oooouuuutttt oooorrrr ccccooooppppyyyy aaaa rrrreeeeccccuuuurrrrssssiiiivvvveeee ddddaaaattttaaaa ssssttttrrrruuuuccccttttuuuurrrreeee????
-
- The Data::Dumper module on CPAN is nice for printing out
- data structures, and FreezeThaw for copying them. For
- example:
-
- use FreezeThaw qw(freeze thaw);
- $new = thaw freeze $old;
-
- Where $old can be (a reference to) any kind of data
- structure you'd like. It will be deeply copied.
-
- HHHHoooowwww ddddoooo IIII ddddeeeeffffiiiinnnneeee mmmmeeeetttthhhhooooddddssss ffffoooorrrr eeeevvvveeeerrrryyyy ccccllllaaaassssssss////oooobbbbjjjjeeeecccctttt????
-
- Use the UNIVERSAL class (see the _U_N_I_V_E_R_S_A_L manpage).
-
- HHHHoooowwww ddddoooo IIII vvvveeeerrrriiiiffffyyyy aaaa ccccrrrreeeeddddiiiitttt ccccaaaarrrrdddd cccchhhheeeecccckkkkssssuuuummmm????
-
- Get the Business::CreditCard module from CPAN.
-
- AAAAUUUUTTTTHHHHOOOORRRR AAAANNNNDDDD CCCCOOOOPPPPYYYYRRRRIIIIGGGGHHHHTTTT
- Copyright (c) 1997, 1998 Tom Christiansen and Nathan
- Torkington. All rights reserved.
-
- When included as part of the Standard Version of Perl, or as
- part of its complete documentation whether printed or
- otherwise, this work may be distributed only under the terms
- of Perl's Artistic License. Any distribution of this file
- or derivatives thereof _o_u_t_s_i_d_e of that package require that
- special arrangements be made with copyright holder.
-
- Irrespective of its distribution, all code examples in this
- file are hereby placed into the public domain. You are
- permitted and encouraged to use this code in your own
- programs for fun or for profit as you see fit. A simple
- comment in the code giving credit would be courteous but is
- not required.
-
-
-
-
-
-
-
- Page 29 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111)))) 5555////AAAAuuuugggg////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLFFFFAAAAQQQQ4444((((1111))))
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 30 (printed 10/23/98)
-
-
-
-
-
-
-